package com.gengzp.system.service.impl;

import com.gengzp.common.enums.YesNoEnum;
import com.gengzp.common.exception.BusinessException;
import com.gengzp.common.model.generic.entity.GenericEntity;
import com.gengzp.common.model.pagination.resp.PaginationResponse;
import com.gengzp.common.model.permission.entity.UserRoleRelation;
import com.gengzp.common.model.role.entity.SysRole;
import com.gengzp.common.model.role.req.CreateSysRoleReq;
import com.gengzp.common.model.role.req.EditSysRoleReq;
import com.gengzp.common.model.role.req.PageSysRoleReq;
import com.gengzp.common.model.role.resp.PageSysRoleResp;
import com.gengzp.common.model.role.resp.SearchSysRoleResp;
import com.gengzp.system.facade.PermissionFacade;
import com.gengzp.system.mapper.SysRoleMapper;
import com.gengzp.system.service.SysRoleService;
import com.gengzp.system.utils.OperatorInfoUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName SysRoleServiceImpl
 * @Description
 * @Author gengzp
 * @Date 2025/9/8 19:52
 */
@Service
public class SysRoleServiceImpl implements SysRoleService {

    private static final Logger logger = LoggerFactory.getLogger(SysRoleServiceImpl.class);

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private PermissionFacade permissionFacade;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createSysRole(CreateSysRoleReq req) {
        if (Objects.nonNull(sysRoleMapper.selectSysRoleByName(req.getRoleName()))) {
            throw BusinessException.get("当前角色名称已存在");
        }

        SysRole sysRole = new SysRole();
        sysRole.setRoleName(req.getRoleName());
        sysRole.setRoleDescription(req.getRoleDescription());

        // 用 "," 分隔权限编码
        if (CollectionUtils.isNotEmpty(req.getPermissionCodes())) {
            sysRole.setPermissionCodes(String.join(",", new HashSet<>(req.getPermissionCodes())));
        }

        // 用 "," 分割页面编码
        if (CollectionUtils.isNotEmpty(req.getWebPageCodes())) {
            sysRole.setConsolePageCodes(String.join(",", new HashSet<>(req.getWebPageCodes())));
        }

        sysRoleMapper.insertSysRole(sysRole);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editSysRoleById(EditSysRoleReq req) {
        SysRole sysRoleById = sysRoleMapper.selectSysRoleById(Long.valueOf(req.getId()));
        if (Objects.isNull(sysRoleById)) {
            throw BusinessException.get("当前角色id不存在");
        }

        SysRole sysRoleByName = sysRoleMapper.selectSysRoleByName(req.getRoleName());
        if (Objects.nonNull(sysRoleByName) && !Objects.equals(Long.valueOf(req.getId()), sysRoleByName.getId())) {
            throw BusinessException.get("当前角色名称已存在");
        }

        sysRoleById.setRoleName(req.getRoleName());
        sysRoleById.setRoleDescription(req.getRoleDescription());
        sysRoleMapper.updateSysRoleById(sysRoleById);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeSysRoleById(Long roleId) {
        SysRole sysRole = sysRoleMapper.selectSysRoleById(roleId);
        if (Objects.isNull(sysRole)) {
            throw BusinessException.get("当前角色id不存在");
        }

        sysRole.setIsDeleted(YesNoEnum.YES.getCode());
        sysRoleMapper.deleteSysRoleById(sysRole);

        // 删除该角色所有关联关系
        permissionFacade.removeUserRoleRelationsByRoleId(roleId);
    }

    @Override
    public SearchSysRoleResp searchSysRoleById(Long roleId) {
        SysRole sysRole = sysRoleMapper.selectSysRoleById(roleId);
        if (Objects.isNull(sysRole)) {
            throw BusinessException.get("当前角色id不存在");
        }

        SearchSysRoleResp searchSysRoleResp = new SearchSysRoleResp();
        searchSysRoleResp.setId(String.valueOf(sysRole.getId()));
        searchSysRoleResp.setRoleName(sysRole.getRoleName());
        searchSysRoleResp.setRoleDescription(sysRole.getRoleDescription());
        searchSysRoleResp.setPermissions(Lists.newArrayList());
        searchSysRoleResp.setConsolePages(Lists.newArrayList());

        // 组装接口权限集合
        if (StringUtils.isNotBlank(sysRole.getPermissionCodes())) {
            searchSysRoleResp.getPermissions().addAll(
                    permissionFacade.searchPermissionDtosByPermissionCodes(
                            Arrays.asList(sysRole.getPermissionCodes().split(",")))
            );
        }

        // 组装控制台页面权限集合
        if (StringUtils.isNotBlank(sysRole.getConsolePageCodes())) {
            searchSysRoleResp.getConsolePages().addAll(
                    permissionFacade.searchConsolePagesByPageCodes(
                            Arrays.asList(sysRole.getConsolePageCodes().split(",")))
            );
        }

        searchSysRoleResp.setCreatedBy(String.valueOf(sysRole.getCreatedBy()));
        searchSysRoleResp.setCreatedTime(sysRole.getCreatedTime());
        searchSysRoleResp.setLastModifiedBy(String.valueOf(sysRole.getLastModifiedBy()));
        searchSysRoleResp.setLastModifiedTime(sysRole.getLastModifiedTime());
        // 填充操作人信息
        OperatorInfoUtils.fillInGenericRespOperatorInformation(searchSysRoleResp);

        return searchSysRoleResp;
    }

    @Override
    public PaginationResponse<PageSysRoleResp> pageQuerySysRole(PageSysRoleReq req) {
        List<SysRole> sysRoles = sysRoleMapper.pageQuerySysRole(req);
        if (CollectionUtils.isEmpty(sysRoles)) {
            return PaginationResponse.get(Collections.emptyList(), req);
        }

        List<PageSysRoleResp> result = sysRoles.stream().map(sysRole -> {
            PageSysRoleResp resp = new PageSysRoleResp();
            resp.setId(String.valueOf(sysRole.getId()));
            resp.setRoleName(sysRole.getRoleName());
            resp.setRoleDescription(sysRole.getRoleDescription());
            resp.setRelationPermissionCount(
                    StringUtils.isBlank(sysRole.getPermissionCodes()) ? 0 :
                            sysRole.getPermissionCodes().split(",").length);
            resp.setRelationConsolePageCount(
                    StringUtils.isBlank(sysRole.getConsolePageCodes()) ? 0 :
                            sysRole.getConsolePageCodes().split(",").length);
            resp.setCreatedBy(String.valueOf(sysRole.getCreatedBy()));
            resp.setCreatedTime(sysRole.getCreatedTime());
            resp.setLastModifiedBy(String.valueOf(sysRole.getLastModifiedBy()));
            resp.setLastModifiedTime(sysRole.getLastModifiedTime());
            return resp;
        }).toList();

        // 用户角色关联关系映射 key:角色id    value:用户角色关联关系
        Map<Long, List<UserRoleRelation>> userRoleRelationMap = Maps.newHashMap();
        List<UserRoleRelation> userRoleRelations = permissionFacade
                .searchUserRoleRelationsByRoleIds(sysRoles.stream().map(GenericEntity::getId).collect(Collectors.toList()));
        if (CollectionUtils.isNotEmpty(userRoleRelations)) {
            userRoleRelationMap = userRoleRelations.stream().collect(Collectors.groupingBy(UserRoleRelation::getRoleId));
        }
        for (PageSysRoleResp resp : result) {
            List<UserRoleRelation> relations = userRoleRelationMap.get(Long.valueOf(resp.getId()));
            resp.setRelationUserCount(CollectionUtils.isEmpty(relations) ? 0 : relations.size());
        }

        // 填充操作人信息
        OperatorInfoUtils.fillInGenericRespOperatorInformation(result);

        return PaginationResponse.get(result, req);
    }

}
